import java.net.URL;
import java.rmi.RemoteException;
import java.sql.*;
import java.util.*;

import com.util.vmwareops.VmTask;
import com.vmware.vim25.VmotionInterfaceNotEnabled;
import com.vmware.vim25.mo.*;

import javax.sql.DataSource;
import javax.xml.crypto.Data;

public class Main {
    public static void main(String[] args)  throws Exception {
        ServiceInstance serviceInstance= new ServiceInstance(new URL("https://182.242.8.11:443/sdk"), "administrator@vsphere.local", "VMware123!", true);
        // 获取根目录
        Folder rootFolder = serviceInstance.getRootFolder();

        /*// 获取集群资源
        ManagedEntity[] managedEntityList;
        managedEntityList = new InventoryNavigator(rootFolder).searchManagedEntities("ClusterComputeResource");
        // 遍历集群资源，获取物理主机和虚拟机
        // 获取集群列表
        List<ClusterComputeResource> clusterList = new ArrayList<ClusterComputeResource>();
        for (ManagedEntity entity : managedEntityList) {
            ClusterComputeResource cluster = (ClusterComputeResource) entity;
            clusterList.add(cluster);
        }

        for(ClusterComputeResource cluster : clusterList) {
            Network[] networks = cluster.getNetworks();
            for(Network network : networks) {
                System.out.println(network.getName());
            }

            Datastore [] datastores = cluster.getDatastores();
            for(Datastore datastore : datastores) {
                System.out.println(datastore.getName());
            }
        }*/
        String vcName = "zjtestvcsa01.bocomdsk.com";
        String vmName = "Test_umount";
        String hostDestination = "531testserver002.bocomdsk.com";
        String dsDestination = "";
        int NumCpu = 4;
        int NumMem = 6;

//        VmTask VmTask = new VmTask(vcName);
//        VmTask.vmReConfig(vcName,vmName,NumCpu,NumMem);
        //VmTask.VMotion(vmName,hostDestination,dsDestination,"DistributedVirtualPortgroup","DistributedVirtualPortgroup","DS_QUSTST_182.242.100.x","DS_139.97.200.x_NBU_MNG");

//        ManagedEntity[] managedEntities;
//        managedEntities = new InventoryNavigator(rootFolder).searchManagedEntities("Datastore");
//        for (ManagedEntity ds : managedEntities)
//        {
//            System.out.println(ds.getName());
//        }
    }


    private static List<VirtualMachine> getVirtualMachines(ServiceInstance si) {
        List<VirtualMachine> vmList = new ArrayList<VirtualMachine>();
        try {
            Folder rootFolder = si.getRootFolder();
            ManagedEntity[] managedEntityList;
            managedEntityList = new InventoryNavigator(rootFolder)
                    .searchManagedEntities("VirtualMachine");
            if (managedEntityList != null) {
                for (ManagedEntity entity : managedEntityList) {
                    VirtualMachine vm = (VirtualMachine) entity;
                    Datastore[] datastores = vm.getDatastores();
                    // 获取虚拟机存储
                    //for(Datastore datastore : datastores) {
                    //    System.out.println(datastore.getName());
                    //}
                    // 根据vm获取虚拟机
                    HostSystem result =  new HostSystem(si.getServerConnection(),vm.getRuntime().getHost());
                    System.out.println(result.getName() + "xxxxxxxxxxxxxxxxxxxxxxx");
                    System.out.println(vm.getName() + " " + vm.getConfig().hardware.numCPU + " " + vm.getConfig().hardware.memoryMB);
                    System.out.println(vm.getGuest().hostName + " " + vm.getGuest().ipAddress);


                    Network[] net = vm.getNetworks();
                    for(Network n : net) {
                        System.out.println(n.getName());
                    }
                    System.out.println("-----------------------------");
                }
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return vmList;
    }

    private static void printVMs(List<VirtualMachine> vmList) {
        for(VirtualMachine vm:vmList) {
            System.out.println(vm.getName());
        }

    }

    public static class JDBCConnectionPool {
        private static LinkedList freeConnection = new LinkedList();
        private static HashSet usedConnection = new HashSet();
        private static String url = "jdbc:mysql://localhost:3306/vmwareops?useSSL=false&serverTimezone=UTC";
        private static String username = "root";
        private static String password = "root1234";
        private static int maxConnect = 5;
        private static int minConnect = 1;
        static final boolean DEBUG = false;
        static private long lastClearClosedConnection = System.currentTimeMillis();
        public static long CHECK_CLOSED_CONNECTION_TIME = 5000;

        // 初始化mysql的jdbc driver
        static {
            try {
                initDriver();
            } catch(InstantiationException e) {
                e.printStackTrace();
            } catch(IllegalAccessException e) {
                e.printStackTrace();
            } catch(ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        private static void initDriver() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            Driver driver = null;
            driver = (Driver)Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
            try {
                DriverManager.registerDriver(driver);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        // 获取jdbc连接
        public static synchronized Connection getConnnection() {
            //先将过期的连接清理掉
            clearClosedConnection();

            //确保有可用的连接
            ensureFreeConnectionPool();

            // 从空闲的连接池中获取一个未使用的连接
            while(freeConnection.size() > 0) {
                try {
                    Connection con = (Connection)freeConnection.removeFirst();
                    if(con.isClosed()) {
                        continue;
                    }
                    usedConnection.add(con);
                    return con;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            // 如果没有可用连接，返回null
            return null;

        }
        private static void ensureFreeConnectionPool() {
            // 如果有可用的连接，直接返回
            if(freeConnection.size() > 0) {
                return;
            }
            // 如果空闲连接池为空，需要新建一些连接共应用使用
            // 如果当前已经建立的连接超过了定义的最大连接数，则返回null，表示没有可用的连接
            // 如果还有空间可以建立连接，则获取一个要建立的连接数newCount，newCount+已经建立的连接需要小于最大的连接数限制
            int currentConnectionCount = usedConnection.size() + freeConnection.size();
            if(currentConnectionCount >= maxConnect) {
                return;
            }
            int newCount = getIncreasingConnection();
            if(newCount > maxConnect - currentConnectionCount) {
                newCount = maxConnect - currentConnectionCount;
            }
            // 新建可用的连接加入到空闲连接池中
            Connection con = null;
            for(int i=0;i<newCount;i++) {
                con = getNewConnection();
                if(con != null ){
                    freeConnection.add(con);
                }
            }
        }
        private static Connection getNewConnection() {
            try {
                Connection con = DriverManager.getConnection(url, username, password);
                return con;
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return null;
        }
        private static int getIncreasingConnection() {
            int count = (usedConnection.size() + freeConnection.size()) / 5;
            return count >= 1 ? count : 1;
        }
        private static void clearClosedConnection() {
            long time = System.currentTimeMillis();
            if(time - lastClearClosedConnection < CHECK_CLOSED_CONNECTION_TIME) {
                return;
            }
            lastClearClosedConnection = time;
            Iterator iterator = freeConnection.iterator();
            while(iterator.hasNext()) {
                Connection con = (Connection) iterator.next();
                try {
                    if(con.isClosed()) {
                        iterator.remove();
                    }
                } catch (SQLException e) {
                    iterator.remove();
                    e.printStackTrace();
                }
            }

        }
        private static int closePool(Iterator iterator) {
            int count = 0;
            while(iterator.hasNext()) {
                try {
                    ((Connection)iterator.next()).close();
                    count++;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            return count;
        }
        public static int closeAll() {
            int count = 0;
            Iterator iterator = usedConnection.iterator();
            count += closePool(iterator);
            usedConnection.clear();

            iterator = freeConnection.iterator();
            count += closePool(iterator);
            freeConnection.clear();

            return count;
        }
        private static synchronized void close(Connection con) {
            boolean exist = usedConnection.remove(con);
            if(exist) {
                freeConnection.add(con);
            }
        }

    }
}